﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace FileCopy
{
    public class WinAPI
    {
        [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int SHFileOperation(SHFileOpStruct lpFileOp);

        /// <summary>
        /// 文件名分割符
        /// </summary>
        private const string FILE_SPLITER = "/0";

        /// <summary>
        /// Shell文件操作数据类型
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private class SHFileOpStruct
        {
            public IntPtr hwnd;
            /// <summary>
            /// 设置操作方式
            /// </summary>
            public wFunc wFunc;
            /// <summary>
            /// 源文件路径
            /// </summary>
            public string pFrom;
            /// <summary>
            /// 目标文件路径
            /// </summary>
            public string pTo;
            /// <summary>
            /// 文件操作标识
            /// </summary>
            public FileOpFlags fFlags;
            /// <summary>
            /// 监测有无中止
            /// </summary>
            public bool fAnyOperationsAborted;
            public IntPtr hNameMappings;
            /// <summary>
            /// 设置标题
            /// </summary>
            public string lpszProgressTitle;
        }

        /// <summary>
        /// 文件操作方式
        /// </summary>
        private enum wFunc
        {
            /// <summary>
            /// 移动
            /// </summary>
            FO_MOVE = 0x0001,
            /// <summary>
            /// 复制
            /// </summary>
            FO_COPY = 0x0002,
            /// <summary>
            /// 删除
            /// </summary>
            FO_DELETE = 0x0003,
            /// <summary>
            /// 重命名
            /// </summary>
            FO_RENAME = 0x0004
        }

        private enum FileOpFlags
        {
            /// <summary>
            /// 指定了多个目标文件，而不是单个目录
            /// </summary>
            FOF_MULTIDESTFILES = 0x1,
            /// <summary>
            /// 不再使用
            /// </summary>
            FOF_CONFIRMMOUSE = 0x2,
            /// <summary>
            /// 不显示一个进度对话框
            /// </summary>
            FOF_SILENT = 0x4,
            /// <summary>
            /// 碰到有抵触的名字时，自动分配前缀
            /// </summary>
            FOF_RENAMEONCOLLISION = 0x8,
            /// <summary>
            /// 不对用户显示提示
            /// </summary>
            FOF_NOCONFIRMATION = 0x10,
            /// <summary>
            /// 填充 hNameMappings 字段，必须使用 SHFreeNameMappings 释放
            /// </summary>
            FOF_WANTMAPPINGHANDLE = 0x20,
            /// <summary>
            /// 允许撤销
            /// </summary>
            FOF_ALLOWUNDO = 0x40,
            /// <summary>
            /// 只对*.*文件进行操作
            /// </summary>
            FOF_FILESONLY = 0x80,
            /// <summary>
            /// 简单进度条，意味着不显示文件名。
            /// </summary>
            FOF_SIMPLEPROGRESS = 0x100,
            /// <summary>
            /// 建新目录时不需要用户确定
            /// </summary>
            FOF_NOCONFIRMMKDIR = 0x200,
            /// <summary>
            /// 不显示出错用户界面
            /// </summary>
            FOF_NOERRORUI = 0x400,
            /// <summary>
            /// 不要复制文件的安全属性。
            /// </summary>
            FOF_NOCOPYSECURITYATTRIBS = 0x800,
            /// <summary>
            /// 不递归目录
            /// </summary>
            FOF_NORECURSION = 0x1000,
            /// <summary>
            /// 不以组的形式移动连接的文件。只移动指定的文件。
            /// </summary>
            FOF_NO_CONNECTED_ELEMENTS = 0x2000,
            /// <summary>
            /// 如果一个文件在删除和回收操作过程中被破坏,发送一个警告。该标志部分重载FOF_NOCONFIRMATION
            /// </summary>
            FOF_WANTNUKEWARNING = 0x4000,
            FOF_NORECURSEREPARSE = 0x8000,
        }

        public static int Copy(string sourceFiles, string targetFiles)
        {
            SHFileOpStruct pm = new SHFileOpStruct();
            pm.wFunc = wFunc.FO_COPY;
            //设置对话框标题，在win7中无效
            pm.lpszProgressTitle = "复制文件";
            pm.pFrom = sourceFiles;
            pm.pTo = targetFiles;
            pm.fFlags = FileOpFlags.FOF_NOCONFIRMATION | FileOpFlags.FOF_MULTIDESTFILES | FileOpFlags.FOF_ALLOWUNDO;
            return SHFileOperation(pm);
        }
    }
}
